﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MyMainSite.Models.Admin;
using System.Web.Security;
using MyMainSite.Repositories;
using DotNetX;
using MyMainSite.Factories;
using System.IO;

namespace MyMainSite.Controllers
{
    public class AdminController : Controller
    {
        //
        // GET: /Admin/

		[Authorize]
        public ActionResult Index()
        {
            return View();
        }

		public ActionResult Logon()
		{
			return this.View();
		}

		[HttpPost]
		public ActionResult Logon(LogonModel req)
		{
			bool res = BlogUserRepository.ValidateUser(req.UserName.ToEmptyStringIfNull(), req.Password.ToEmptyStringIfNull());

			if (res)
			{
				// from http://www.codethinked.com/setting-up-authentication-in-aspnet-mvc
				var authTicket = new FormsAuthenticationTicket(1, req.UserName, DateTime.Now,
													   DateTime.Now.AddMinutes(30), true, String.Empty);

				string cookieContents = FormsAuthentication.Encrypt(authTicket);
				var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, cookieContents)
				{
					Expires = authTicket.Expiration,
					Path = FormsAuthentication.FormsCookiePath
				};

				if (this.HttpContext != null)
				{
					this.HttpContext.Response.Cookies.Add(cookie);
				}
			}

			if(res)
				return this.RedirectToAction("Index", "Admin", new LogonModel() { LogonResult = res });
			else
				return this.View(new LogonModel() { LogonResult = res });
		}

		public ActionResult Logout()
		{
			FormsAuthentication.SignOut();

			return RedirectToAction("Index", "Admin", new LogonModel());
		}

		[Authorize]
		public ActionResult Projects()
		{
			IProjectRepository repo = RepositoryFactory<ProjectRepositoryImplemented>.GetRepository();

			ProjectsModel model = new ProjectsModel();
			model.Projects = repo.GetProjects();

			return this.View(model);
		}

		[Authorize]
		public ActionResult NewProject()
		{
			return this.View(new NewProjectModel());
		}

		[HttpPost, ValidateInput(false)]
		public ActionResult NewProject(int? projectId, string textName, string textDescription,
			string textSourceCodeUrl, string textFriendlyUrl, string textBugzXUrl, string textAndroidMarketUrl)
		{
			FormChecker checker = new FormChecker();
			IProjectRepository repo = new ProjectRepositoryImplemented();

			Stream s = null;

			foreach (string file in Request.Files)
			{
				HttpPostedFileBase hpf = Request.Files[file];
				if (hpf.ContentLength == 0)
					continue;

				s = hpf.InputStream;
			}

			if (s == null)
				checker.AddError("Please select an image");

			checker.GetString(textName, "Name");
			checker.GetString(textDescription, "Description");
			checker.GetString(textFriendlyUrl, "Friendly Url");

			if (!String.IsNullOrWhiteSpace(textName))
				if (!repo.IsProjectNameUnique(textName))
					checker.AddError(String.Format("There is already a project with the name '{0}'. Please select another name.",
						textName));

			if (!String.IsNullOrWhiteSpace(textFriendlyUrl))
				if (!repo.IsProjectFriendlyUrlUnique(textFriendlyUrl))
					checker.AddError(String.Format("There is already a project with the friendly url '{0}'. Please select another url.",
						textFriendlyUrl));

			if (checker.HasErrors)
				return this.View(new NewProjectModel() { ErrorMessage = checker.ErrorsByBRTag });

			BinaryReader reader = new BinaryReader(s);
			byte[] data = reader.ReadBytes((int)s.Length);

			if (repo.AddProject(textName, textDescription, textFriendlyUrl, textSourceCodeUrl, textBugzXUrl, textAndroidMarketUrl, data) <= 0)
				return this.View(new NewProjectModel() { ErrorMessage = "Failed to create project." });

			// we want a blog automatically made for this project
			BlogRepository.AddBlogForProject(repo.GetProjectByName(textName).ProjectId, 1, repo); // there is only one user at the moment.... me :)

			return this.RedirectToAction("project", new { projectId = repo.GetProjectByName(textName).ProjectId });
		}

		[Authorize]
		public ActionResult Project(int projectId)
		{
			IProjectRepository repo = RepositoryFactory<ProjectRepositoryImplemented>.GetRepository();

			var project = repo.GetProjectById(projectId);
			if (project == null)
			{
				return this.RedirectToAction("error", "error");
			}

			ProjectModel model = new ProjectModel(project);

			return this.View(model);
		}

		[Authorize]
		public ActionResult NewProjectBuild(int projectId)
		{
			return this.View(new NewProjectBuildModel(projectId));
		}

		[HttpPost, ValidateInput(false)]
		public ActionResult NewProjectBuild(int projectId, string textName, string textVersion)
		{
			FormChecker checker = new FormChecker();
			ProjectBuildRepository repo = new ProjectBuildRepository();

			Stream s = null;
			string fileName = String.Empty;

			foreach (string file in Request.Files)
			{
				HttpPostedFileBase hpf = Request.Files[file];
				if (hpf.ContentLength == 0)
					continue;

				s = hpf.InputStream;
				fileName = hpf.FileName;
			}

			if (s == null)
				checker.AddError("Please select a file to upload");

			checker.GetString(textName, "Name");
			checker.GetVersion(textVersion, "Version");

			if (!checker.HasErrors)
				if (!String.IsNullOrWhiteSpace(textName) && !String.IsNullOrWhiteSpace(textVersion))
					if (!repo.IsProjectBuildNameAndVersionUnique(textName, new Version(textVersion)))
						checker.AddError(String.Format("There is already a project build with the name '{0}' and version '{1}'.",
							textName, textVersion));

			if (checker.HasErrors)
				return this.View(new NewProjectBuildModel(projectId) { ErrorMessage = checker.ErrorsByBRTag });

			BinaryReader reader = new BinaryReader(s);
			byte[] data = reader.ReadBytes((int)s.Length);

			if (repo.AddBuild(projectId, textName, fileName, (int)s.Length, data, new Version(textVersion)) <= 0)
				return this.View(new NewProjectBuildModel(projectId) { ErrorMessage = "Failed to create project build." });

			return this.RedirectToAction("project", new { projectId = projectId });
		}
    }
}
